package cn.gailvlun.gll.widget

import android.annotation.SuppressLint
import android.content.Context
import android.media.MediaPlayer
import android.support.annotation.IntDef
import android.support.v7.widget.AppCompatSeekBar
import android.util.AttributeSet
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.SeekBar
import android.widget.TextView
import cn.gailvlun.gll.R
import cn.gailvlun.gll.util.LogUtil
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import java.text.MessageFormat
import java.util.concurrent.TimeUnit

enum class PlayViewState {
    PREVIOUS, NEXT
}

interface OnPlayViewStateChangedListener {
    fun onPlayViewStateChanged(playViewState: PlayViewState)
}


class PlayView : LinearLayout {

    companion object {
        const val INVALID = -1L
        const val NOT_PLAYED = 0L
        const val PLAYING = 1L
        const val PAUSED = 2L
        
        const val COMPLETED = 3L

        @IntDef(INVALID, NOT_PLAYED, PLAYING, PAUSED, COMPLETED)
        annotation class UniqueState
    }

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        initView()
    }

    @UniqueState
    private var mState: Long? = INVALID

    var mPlayListener: OnPlayViewStateChangedListener? = null





















    private lateinit var tvCurrent: TextView
    private lateinit var tvAmount: TextView
    private lateinit var ivCenter: ImageView
    private lateinit var ivPrevious: ImageView
    private lateinit var ivNext: ImageView
    private lateinit var acsb: AppCompatSeekBar

    @SuppressLint("ClickableViewAccessibility")
    fun initView() {
        orientation = VERTICAL
        View.inflate(context, R.layout.play_view, this)

        tvCurrent = findViewById(R.id.tv_current)
        tvAmount = findViewById(R.id.tv_amount)
        ivCenter = findViewById(R.id.iv_center)
        ivPrevious = findViewById(R.id.iv_previous)
        ivNext = findViewById(R.id.iv_next)
        acsb = findViewById(R.id.acsb)

        ivCenter.setOnClickListener {
            when (mState) {
                INVALID -> {
                    LogUtil.d("Sorry bro, If it's invalid, you can't do anything about it")
                }
                NOT_PLAYED -> {
                    
                    ivCenter.setImageResource(R.drawable.ic_pause_wht)
                    
                    play()
                }
                PLAYING -> {
                    
                    ivCenter.setImageResource(R.drawable.ic_play_wht)
                    
                    pause()
                }
                PAUSED -> {
                    
                    ivCenter.setImageResource(R.drawable.ic_pause_wht)
                    
                    play()
                }
                COMPLETED -> {
                    
                    ivCenter.setImageResource(R.drawable.ic_pause_wht)
                    
                    play()
                }
            }
        }

        ivPrevious.setOnClickListener {
            mPlayListener?.onPlayViewStateChanged(PlayViewState.PREVIOUS)
        }

        ivNext.setOnClickListener {
            mPlayListener?.onPlayViewStateChanged(PlayViewState.NEXT)
        }


        acsb?.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                if (fromUser) {
                    mMediaPlayer?.seekTo(progress)
                    setProgressText(progress)
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {

            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {

            }

        })
    }

    private var mMediaPlayer: MediaPlayer? = null

    private var mDuration: Int? = null


    fun setUrl(dataSource: String) {
        mMediaPlayer = MediaPlayer()
        try {
            mMediaPlayer?.setDataSource(dataSource)
            mMediaPlayer?.prepareAsync()
            mMediaPlayer?.setOnPreparedListener {
                mDuration = mMediaPlayer?.duration
                acsb.max = mDuration!!
                
                setMaxText(mDuration)

                acsb.progress = 0
                setProgressText(0)

                mState = NOT_PLAYED
            }
        } catch (e: Exception) {
            e.printStackTrace()
            return
        }
    }

    private fun setProgressText(currentPosition: Int) {
        tvCurrent.text = getLongFromMill(currentPosition)
    }

    private fun setMaxText(maxPosition: Int?) {
        tvAmount.text = getLongFromMill(maxPosition)
    }

    private fun getLongFromMill(mill: Int?): String {
        if (mill != null) {
            return format("{0, number, 00}:{1, number,00}", mill.div(1000 * 60), mill.div(1000) % 60)
        } else {
            return "00:00"
        }
    }

    fun format(pattern: String, vararg arguments: Any): String {
        return MessageFormat.format(pattern, *arguments)
    }

    fun play() {
        mMediaPlayer?.start()
        mMediaPlayer?.setOnCompletionListener {
            
            mState = COMPLETED
            ivCenter.setImageResource(R.drawable.ic_play_wht)
            acsb.progress = 0
            setProgressText(0)

            disposable?.dispose()
        }

        mState = PLAYING

        Observable.interval(0, 100, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<Long> {
                    override fun onNext(t: Long) {
                        acsb.progress = mMediaPlayer?.currentPosition!!
                        setProgressText(mMediaPlayer?.currentPosition!!)
                    }

                    override fun onError(e: Throwable) {

                    }

                    override fun onComplete() {

                    }

                    override fun onSubscribe(d: Disposable) {
                        disposable = d
                    }
                })
    }

    private var disposable: Disposable? = null

    fun pause() {
        mState = PAUSED

        disposable?.dispose()
        mMediaPlayer?.pause()
    }

    fun stop() {
        pause()
        mMediaPlayer?.stop()
        ivCenter.setImageResource(R.drawable.ic_play_wht)


    }

    fun switch() {
        
        acsb.progress = 0
        acsb.max = 1

        setProgressText(0)
        setMaxText(0)

        mState = INVALID
        ivCenter.setImageResource(R.drawable.ic_play_wht)

        disposable?.dispose()
        mMediaPlayer?.reset()
    }

    fun onDestroy() {
        disposable?.dispose()
        mMediaPlayer?.stop()
        mMediaPlayer?.release()
    }
}